package algorithm.sort;

import com.google.common.collect.Lists;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.List;

public class BoolBuilder {
  public Occur occur;

  public String exper;

  public List<BoolBuilder> childBoolBuilder = Lists.newLinkedList();

  protected static final String RWQUERY_PREFIX = "(";

  protected static final String RWQUERY_SUFFIX = ")";

  private BoolBuilder() {
    this.occur = Occur.AND;
  }

  public BoolBuilder(String exper) {
    this.exper = exper;
  }

  public BoolBuilder(Occur occur) {
    this.occur = occur;
  }

  public BoolBuilder addChildBool(BoolBuilder childBoolBuilder) {
    this.childBoolBuilder.add(childBoolBuilder);
    return this;
  }

  public static void main(String[] args) {

    BoolBuilder b = new BoolBuilder("haha");

    BoolBuilder d = new BoolBuilder("ddd");
    BoolBuilder f = new BoolBuilder("ffff");

    BoolBuilder yyy = new BoolBuilder("yyy");

    BoolBuilder a = new BoolBuilder(Occur.AND);
    BoolBuilder c = new BoolBuilder(Occur.OR);
    BoolBuilder xx = new BoolBuilder(Occur.OR);
    xx.addChildBool(yyy);
    c.addChildBool(d).addChildBool(f);
    a.addChildBool(b).addChildBool(c).addChildBool(xx);

    System.out.println(a.builder());


    BoolBuilder kk = new BoolBuilder(Occur.OR);
    kk.addChildBool(new BoolBuilder("22"));
    BoolBuilder ll = new BoolBuilder(Occur.OR);
    ll.addChildBool(new BoolBuilder(Occur.OR)).addChildBool(new BoolBuilder("1"));
    BoolBuilder aa = new BoolBuilder(Occur.AND);
    BoolBuilder boolBuilder = aa.addChildBool(kk).addChildBool(ll);
    System.out.println(boolBuilder.builder());
  }

  public String builder() {
    return builder(this);
  }

  public String builder(BoolBuilder boolBuilder) {
    if (CollectionUtils.isEmpty(boolBuilder.childBoolBuilder)) {
      return boolBuilder.exper;
    }
    List<String> childExper = Lists.newLinkedList();
    for (BoolBuilder childBoolBuilder : boolBuilder.childBoolBuilder) {
      childExper.add(builder(childBoolBuilder));
    }
    childExper.removeIf(s -> StringUtils.isBlank(s)); //空字符串移除
    if (childExper.size() == 0) return "";
    if (childExper.size() == 1) return childExper.get(0);
    return formatRwQuery(StringUtils.join(childExper, boolBuilder.occur.getDesc()));
  }

  public String formatRwQuery(String rwQuery) {
    StringBuilder rwQuerysb = new StringBuilder(rwQuery);
    rwQuerysb.insert(0, RWQUERY_PREFIX);
    rwQuerysb.append(RWQUERY_SUFFIX);
    return rwQuerysb.toString();
  }

  public enum Occur {
    AND(" AND "), OR(" OR ");

    public String desc;

    Occur(String s) {
      this.desc = s;
    }

    public String getDesc() {
      return this.desc;
    }

  }

}
